<?php

namespace app\api\model;

use app\event\mobile\MobilePaySuccess;
use app\model\AgentSalesman;
use think\Exception;
use think\facade\Db;
use app\common\model\FinanceStat;
use think\facade\Log;

class Mobile
{
    private $error = '';
    private static $amountList = [
        30,
        50,
        100,
        200,
        // 300,
        // 400,
        // 500,
    ];

    public static function getAmountList()
    {
        return self::$amountList;
    }

    /**
     * 创建充值订单.
     */
    public function create($params)
    {
        $mobile = $params['mobile'] ?? '';
        $amount = $params['amount'] ?? '';
        $sale_discount = $params['sale_discount'];
        $settle_discount = $params['settle_discount'];

        $supplierInfo = Db::table('mobile_supplier')
            ->field('discount_slow, discount_fast, discount_slow_all, discount_fast_all')
            ->where('id', $params['mobile_supplier_id'])
            ->find();
        if (!$supplierInfo) {
            $this->error = '供应商不存在';

            return false;
        }
        $supplierInfo['discount_slow_all'] = json_decode($supplierInfo['discount_slow_all'], true);
        $supplierInfo['discount_fast_all'] = json_decode($supplierInfo['discount_fast_all'], true);

        if (empty($mobile)) {
            $this->error = '请填写手机号';

            return false;
        }
        if (!checkMobile($mobile)) {
            $this->error = '手机号码格式有误';

            return false;
        }
        if (empty($amount)) {
            $this->error = '请选择充值金额';

            return false;
        }
        if (!in_array($amount, self::$amountList)) {
            $this->error = '充值金额有误';

            return false;
        }

        // 预充模式，判断代理商账户余额
        if (SETTLE_TYPE_PREPAY == $params['settle_type']) {
            $balance = Db::name('agent')
                ->where('id', $params['agent_id'])
                ->where('status', 1)
                ->value('balance');
            if (empty($balance) || $balance < yuan2fen($amount)) {
                $this->error = '商户账户余额不足';

                return false;
            }
        }

        $orderId = $this->generateOrderId();
        if (false === $orderId) {
            $this->error = '订单号生成失败，请重试';

            return false;
        }

        $payLog = [
            'agent_id' => $params['agent_id'],
            'channel_id' => $params['channel_id'],
            'user_id' => $params['user_id'],
            'pay_channel' => 1,
            'order_id' => $orderId,
            'mobile' => $mobile,
            'amount' => yuan2fen($amount),
            'status' => 1,
            'sale_discount' => $sale_discount,
            'sale_price' => intval(strval($sale_discount * $amount)),
            'settle_discount' => $settle_discount,
            'settle_price' => intval(strval($settle_discount * $amount)),
            'trade_type' => $params['trade_type'] ?? '',
            'settle_type' => $params['settle_type'],
        ];

        // 供应商价格 计算
        $ispType = getMobileIsp($params['mobile']); // 1移动 2联通 3电信 -1其他
        if (empty($params['is_fast'])) {
            $supplierDiscount = $supplierInfo['discount_slow_all'][$ispType] ?? $supplierInfo['discount_slow'];
        } else {
            $supplierDiscount = $supplierInfo['discount_fast_all'][$ispType] ?? $supplierInfo['discount_fast'];
        }
        $supplierPrice = intval(strval($amount * $supplierDiscount));

        $agentProfit = $payLog['sale_price'] - $payLog['settle_price'];
        $platformProfit = $payLog['settle_price'] - $supplierPrice;

        // 返佣平台不能亏钱
        if ($params['settle_type'] == SETTLE_TYPE_PROFIT && $platformProfit < 0) {
            $this->error = '价格有误，请联系管理员' . __LINE__;

            return false;
        }
        // // 平台亏本 1 块钱，也不让下
        // if ($platformProfit < -100) {
        //     $this->error = '价格有误，请联系管理员。' . __LINE__;

        //     return false;
        // }

        $salesmanId = AgentSalesman::getSalesmanIdByAgentId($params['agent_id'], PRODUCT_MOBILE_SERV);

        $subOrderId = $payLog['order_id'] . '01';
        $order = [
            'agent_id' => $payLog['agent_id'],
            'channel_id' => $payLog['channel_id'],
            'user_id' => $payLog['user_id'],
            'order_id' => $payLog['order_id'],
            'sub_order_id' => $subOrderId,
            'out_order_id' => $subOrderId,
            'mobile' => $mobile,
            'amount' => $payLog['amount'],
            'status' => 1,
            'sale_discount' => $sale_discount,
            'settle_discount' => $settle_discount,
            'sale_price' => $payLog['sale_price'],  // 销售价
            'settle_price' => $payLog['settle_price'],  // 结算价
            'supplier_discount' => $supplierDiscount,
            'supplier_price' => $supplierPrice, // 成本价
            'platform_profit' => $platformProfit, // 平台利润
            'profit' => $agentProfit,   // 代理商利润
            'settle_type' => $params['settle_type'],
            'order_type' => $params['is_fast'] ? 2 : 1, // 充值类型：1慢充 2快充
            'order_from' => ORDER_FROM_H5,
            'mobile_supplier_id' => $params['mobile_supplier_id'],
            'salesman_id' => $salesmanId,
            'ext_data' => $params['ext_data']??'',
        ];

        Db::startTrans();
        try {
            Db::name('pay_log')->insert($payLog);
            Db::name('mobile_order')->insert($order);

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();

            $this->error = '订单生成失败，请稍后重试：' . $e->getMessage();

            return false;
        }

        return compact('payLog', 'orderId');
    }

    /**
     * 生成订单号.
     */
    private function generateOrderId()
    {
        for ($i = 0; $i < 21; ++$i) {
            $orderId = date('ymdHis') . str_pad(mt_rand(0, 99999), 5, STR_PAD_LEFT);
            $id = Db::name('pay_log')
                ->where('order_id', $orderId)
                ->value('id');
            if (empty($id)) {
                return $orderId;
            }
        }

        return false;
    }

    /**
     * 充值成功回调.
     */
    public function handleSuccess($payLog, $payLogUpdate, $orderUpdate)
    {
        Db::name('pay_log')
            ->where('id', $payLog['id'])
            ->update($payLogUpdate);
        if (2 == $payLogUpdate['status']) {
            if (SETTLE_TYPE_PREPAY == $payLog['settle_type']) {
                // 如果是预付，需要判断代理商账户余额
                $balance = Db::name('agent')
                    ->where('id', $payLog['agent_id'])
                    ->lock(true)
                    ->value('balance');
                if (empty($balance) || $balance < $payLog['settle_price']) {
                    $orderUpdate['supplier_status'] = -1;
                    $orderUpdate['remark'] = '账户余额不足';
                } else {
                    Db::name('agent')
                        ->where('id', $payLog['agent_id'])
                        ->dec('balance', $payLog['settle_price'])
                        ->update([
                            'balance_last_updated_at' => date('Y-m-d H:i:s'),
                        ]);
                    $id = Db::name('mobile_order')
                        ->where('order_id', $payLog['order_id'])
                        ->value('id');
                    Db::name('agent_balance_log')
                        ->insert([
                            'agent_id' => $payLog['agent_id'],
                            'type' => BALANCE_MOBILE_RECHARGE,
                            'amount' => -$payLog['settle_price'],
                            'old_balance' => $balance,
                            'new_balance' => $balance - $payLog['settle_price'],
                            'remark' => '话费充值：' . fen2yuan($payLog['amount']) . '元，结算价：' . fen2yuan($payLog['settle_price']) . '元。订单号：' . $payLog['order_id'],
                            'quote_id' => $id,
                            'trade_no' => $payLog['order_id'],
                        ]);
                }
            }
        }

        Db::name('mobile_order')
            ->where('order_id', $payLog['order_id'])
            ->update($orderUpdate);
    }

    /**
     * 充值成功回调【v2.0】
     */
    public function handleSuccessV2($payLog)
    {
        Db::name('pay_log')
            ->where('id', $payLog['id'])
            ->update([
                'status' => 2,
                'trade_no' => $payLog['trade_no'],
                'real_pay_price' => $payLog['real_pay_price'],
            ]);

        $orderUpdate = [
            'status' => 2,
        ];
        if (SETTLE_TYPE_PREPAY == $payLog['settle_type']) {
            // 如果是预付，需要判断代理商账户余额
            $balance = Db::name('agent')
                ->where('id', $payLog['agent_id'])
                ->lock(true)
                ->value('balance');
            if (empty($balance) || $balance < $payLog['settle_price']) {
                $orderUpdate['supplier_status'] = -1;
                $orderUpdate['remark'] = '账户余额不足';
            } else {
                Db::name('agent')
                    ->where('id', $payLog['agent_id'])
                    ->dec('balance', $payLog['settle_price'])
                    ->update([
                        'balance_last_updated_at' => date('Y-m-d H:i:s'),
                    ]);
                $id = Db::name('mobile_order')
                    ->where('order_id', $payLog['order_id'])
                    ->value('id');
                Db::name('agent_balance_log')
                    ->insert([
                        'agent_id' => $payLog['agent_id'],
                        'type' => BALANCE_MOBILE_RECHARGE,
                        'amount' => -$payLog['settle_price'],
                        'old_balance' => $balance,
                        'new_balance' => $balance - $payLog['settle_price'],
                        'remark' => '话费充值：' . fen2yuan($payLog['amount']) . '元，结算价：' . fen2yuan($payLog['settle_price']) . '元。订单号：' . $payLog['order_id'],
                        'quote_id' => $id,
                        'trade_no' => $payLog['order_id'],
                    ]);
            }
        }

        Db::name('mobile_order')
            ->where('order_id', $payLog['order_id'])
            ->update($orderUpdate);

        try {
            Log::info('触发了话费订单支付成功事件');

            event(new MobilePaySuccess($payLog['order_id']));

        } catch (Exception $exception) {

            Log::error($exception->getMessage());

        }


    }

    public function getError()
    {
        return $this->error;
    }
}
